R ile Zaman Serileri Analizi
## Warning: package 'knitr' was built under R version 3.6.3
## Warning: package 'rmdformats' was built under R version 3.6.3
1 Veri Çekme ve Yuvarlama Hesaplamaları
R ile zaman serileriyle çalışmaya yönelik bir araç koleksiyonu, veri işlemede herhangi bir tahminci için önemli bir beceridir. timetk paketi, temel veri düzenleme araçlarını içerir. Bu altbölümde göreceklerimiz:
Zamana Göre Özetleme - Zamana dayalı toplamalar için
Zamana Göre Filtreleme - Karmaşık zamana dayalı filtreleme için
Zamana Göre Doldurma - Boşlukları doldurmak ve düşükten yüksek frekansa geçmek için
Kaydırma - Herhangi bir işlevi kaydırma (yuvarlanma) işlevine dönüştürmek için
Ek kavramlar:
Imputation- Dolgu için Gerekli (Bkz. Düşük - Yüksek Frekans)Gelişmiş Filtreleme - Yeni ekleme süresi% + zaman infix işlemini kullanma (Bkz. Dolgu Verileri: Düşük - Yüksek Frekans)
Görselleştirme - tüm görselleştirmeler için
plot_time_series()
Gerekli kütüphaneler:
library(tidyverse)
library(tidyquant)
library(timetk)
library(lubridate)
library(modeltime)
library(tidymodels)1.1 Veri Seti
Burada FANG veri seti kullanılacaktır:
Günlük,
Düzensiz (tatiller ve haftasonları eksik)
4 grup var (FB, AMZN, NFLX ve GOOG)
glimpse(FANG)Rows: 4,032
Columns: 8
$ symbol <chr> "FB", "FB", "FB", "FB", "FB", "FB", "FB", "FB", "FB", "FB"...
$ date <date> 2013-01-02, 2013-01-03, 2013-01-04, 2013-01-07, 2013-01-0...
$ open <dbl> 27.44, 27.88, 28.01, 28.69, 29.51, 29.67, 30.60, 31.28, 32...
$ high <dbl> 28.18, 28.47, 28.93, 29.79, 29.60, 30.60, 31.45, 31.96, 32...
$ low <dbl> 27.42, 27.59, 27.83, 28.65, 28.86, 29.49, 30.28, 31.10, 30...
$ close <dbl> 28.00, 27.77, 28.76, 29.42, 29.06, 30.59, 31.30, 31.72, 30...
$ volume <dbl> 69846400, 63140600, 72715400, 83781800, 45871300, 10478770...
$ adjusted <dbl> 28.00, 27.77, 28.76, 29.42, 29.06, 30.59, 31.30, 31.72, 30...
adjusted sütunu, her bir gün için düzeltilmil kapanış fiyatlarını içerir.
FANG %>% group_by(symbol) %>% plot_time_series(date, adjusted, .facet_ncol = 2, .interactive = FALSE)Hacim sütunu gün için işlem hacmini (hisse senedinin işlem görme sayısı) içerir.
FANG %>% group_by(symbol) %>% plot_time_series(date, volume, .facet_ncol = 2, .interactive = FALSE)1.2 Zamana Göre Özetleme
summarise_by_time() periyoda göre toplulaştırma yapar:
Periyot toplulaştırma -
SUM()Periyot Düzgünleştirme -
AVERAGE(),FIRST(),LAST()
1.2.1 Periyot Özetleme
Toplam işlem hacmini çeyrek bazında alalım:
SUM()kullanalım.by = "quarter"ile toplulaştıralım.
FANG %>% group_by(symbol) %>% summarise_by_time(date, .by = "quarter", volume = SUM(volume)) %>%
plot_time_series(date, volume, .facet_ncol = 2, .interactive = FALSE, .y_intercept = 0)1.2.2 Periyot Düzgünleştirme
Her aydaki ilk değeri alalım:
Verileri azaltma (yani yumuşatma) etkisi olan ilk değeri elde etmek için
FIRST()kullanabiliriz.MEAN()veyaMEDIAN()kullanabiliriz.Aya göre toplamak için zamana göre özetlemeyi kullanabilriz:
.by = "month".
FANG %>% group_by(symbol) %>% summarise_by_time(date, .by = "month", adjusted = FIRST(adjusted)) %>%
plot_time_series(date, adjusted, .facet_ncol = 2, .interactive = FALSE)1.3 Zamana Göre Filtreleme
Düzeltilmiş hisse senedi fiyatlarını 2013’ün 3. çeyreği için filtreleyelim:
.start_date = "2013-09":"2013-09-01"e dönüştürülür.end_date = "2013":"2013-12-31"e dönüştürülür%+timeve% -timekullanarak filtrelemenin daha gelişmiş bir örneği “Dolgu Verileri: Düşükten Yüksek Frekansa” gösterilmektedir.
FANG %>% group_by(symbol) %>% filter_by_time(date, "2013-09", "2013") %>% plot_time_series(date,
adjusted, .facet_ncol = 2, .interactive = FALSE)1.4 Veri Doldurma
Boşlukları doldurmak (doldurmak) ve düşük frekanstan yüksek frekansa geçmek için kullanılır. Bu işlev, zaman damgalarını doldurmak ve genişletmek için padr paketini kullanır.
1.4.1 Boşlukları Doldurma
Düzensiz veriyi düzenlileştirelim:
Doldurulmuş değerleri
NAolarak bırakacağız..pad_valuekullanarak bir değer ekleyebiliriz veyats_impute_vec ()(daha sonra gösterilmektedir) gibi bir işlevi kullanarak doldurabiliriz.
FANG %>% group_by(symbol) %>% pad_by_time(date, .by = "auto") # Guesses .by = 'day'# A tibble: 5,836 x 8
# Groups: symbol [4]
symbol date open high low close volume adjusted
<chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 FB 2013-01-02 27.4 28.2 27.4 28 69846400 28
2 FB 2013-01-03 27.9 28.5 27.6 27.8 63140600 27.8
3 FB 2013-01-04 28.0 28.9 27.8 28.8 72715400 28.8
4 FB 2013-01-05 NA NA NA NA NA NA
5 FB 2013-01-06 NA NA NA NA NA NA
6 FB 2013-01-07 28.7 29.8 28.6 29.4 83781800 29.4
7 FB 2013-01-08 29.5 29.6 28.9 29.1 45871300 29.1
8 FB 2013-01-09 29.7 30.6 29.5 30.6 104787700 30.6
9 FB 2013-01-10 30.6 31.5 30.3 31.3 95316400 31.3
10 FB 2013-01-11 31.3 32.0 31.1 31.7 89598000 31.7
# ... with 5,826 more rows
1.4.2 Düşükten Yüksek Frekansa
Başlangıç tarihinden itibaren 1 ay boyunca Günlük zaman damgası aralıklarından Saatlik zaman damgası aralıklarına gidelim. Eksik değerleri uygulaylım.
.by = "hour"günlükten saatliğe doldurur.Saatlik verilerin hesaplanması,
period = 1olduğunda doğrusal enterpolasyon yapants_impute_vec()ile gerçekleştirilir.Filtreleme, aşağıdakiler kullanılarak gerçekleştirilir:
- “start”: Bir serinin başlangıcını gösteren özel bir anahtar kelime
FIRST(date) %+time%“1 month”: Sıradaki ilk tarihi seçme ve ardından özel bir ek işlemi, %+time%,"add time"adı verilir. Bu durumda “1 month” eklerim.
FANG %>% group_by(symbol) %>% pad_by_time(date, .by = "hour") %>% mutate_at(vars(open:adjusted),
.funs = ts_impute_vec, period = 1) %>% filter_by_time(date, "start", FIRST(date) %+time%
"1 month") %>% plot_time_series(date, adjusted, .facet_ncol = 2, .interactive = FALSE)1.5 Kayan (Hareketli) Hesaplamalar
slidify() fonksiyonu, herhangi bir fonksiyonu kayan (yuvarlanan) bir pencere fonksiyonuna dönüştürüyor. tibbletime::rollify() ’den kavramlar alır ve bunları R paketi kaydırıcısı ile geliştirir.
1.5.1 Hareketli Ortalamalar
Kısmi pencere yuvarlanması ve başlangıç ve bitiş pencereleri ile “ortalanmış” basit bir hareketli ortalama hesaplayalım:
slidfiy(),AVERAGE()işlevini hareketli ortalamaya dönüştürür.
# Make the rolling function
roll_avg_30 <- slidify(.f = AVERAGE, .period = 30, .align = "center", .partial = TRUE)
# Apply the rolling function
FANG %>% select(symbol, date, adjusted) %>% group_by(symbol) %>% # Apply Sliding Function
mutate(rolling_avg_30 = roll_avg_30(adjusted)) %>% pivot_longer(cols = c(adjusted,
rolling_avg_30)) %>% plot_time_series(date, value, .color_var = name, .facet_ncol = 2,
.smooth = FALSE, .interactive = FALSE)Basit hareketli hesaplamalar için (hareketli ortalama), bu işlemi slidify_vec() ile daha hızlı gerçekleştirebiliriz - Basit özet hareketleri için vektörize edilmiş bir yuvarlama işlevi (ör. mean(), sd(), sum(), vb.)
FANG %>% select(symbol, date, adjusted) %>% group_by(symbol) %>% # Apply roll apply Function
mutate(rolling_avg_30 = slidify_vec(adjusted, ~AVERAGE(.), .period = 30, .partial = TRUE))# A tibble: 4,032 x 4
# Groups: symbol [4]
symbol date adjusted rolling_avg_30
<chr> <date> <dbl> <dbl>
1 FB 2013-01-02 28 30.0
2 FB 2013-01-03 27.8 30.1
3 FB 2013-01-04 28.8 30.2
4 FB 2013-01-07 29.4 30.2
5 FB 2013-01-08 29.1 30.3
6 FB 2013-01-09 30.6 30.3
7 FB 2013-01-10 31.3 30.3
8 FB 2013-01-11 31.7 30.2
9 FB 2013-01-14 31.0 30.1
10 FB 2013-01-15 30.1 30.1
# ... with 4,022 more rows
1.5.2 Hareketli Regresyon
Hareketli regresyon hesaplayalım:
Bu, birden fazla sütunun dahil edilmesini gerektiren karmaşık bir kayan (yuvarlanan) hesaplamadır.
slidify()bunun için oluşturulmuştur.Bir işlevi ayarlamak için çok değişkenli
purrr..1, ..2, ..3, vb. gösterimini kullanacağız.
# Rolling regressions are easy to implement using `.unlist = FALSE`
lm_roll <- slidify(~lm(..1 ~ ..2 + ..3), .period = 90, .unlist = FALSE, .align = "right")
FANG %>% select(symbol, date, adjusted, volume) %>% group_by(symbol) %>% mutate(numeric_date = as.numeric(date)) %>%
# Apply rolling regression
mutate(rolling_lm = lm_roll(adjusted, volume, numeric_date)) %>% filter(!is.na(rolling_lm))# A tibble: 3,676 x 6
# Groups: symbol [4]
symbol date adjusted volume numeric_date rolling_lm
<chr> <date> <dbl> <dbl> <dbl> <list>
1 FB 2013-05-10 26.7 30847100 15835 <lm>
2 FB 2013-05-13 26.8 29068800 15838 <lm>
3 FB 2013-05-14 27.1 24930300 15839 <lm>
4 FB 2013-05-15 26.6 30299800 15840 <lm>
5 FB 2013-05-16 26.1 35499100 15841 <lm>
6 FB 2013-05-17 26.2 29462700 15842 <lm>
7 FB 2013-05-20 25.8 42402900 15845 <lm>
8 FB 2013-05-21 25.7 26261300 15846 <lm>
9 FB 2013-05-22 25.2 45314500 15847 <lm>
10 FB 2013-05-23 25.1 37663100 15848 <lm>
# ... with 3,666 more rows
2 Zaman Serileri Grafikleri
Bu altbölümde, aşağıdakileri yapan bir zaman serisi çizim işlevi olan plot_time_series() üzerine odaklanılmıştır:
Etkileşimli
plotlyçizimleri (uygulamaları keşfetmek ve parlak hale getirmek için harika)20’den fazla
ggplot2satırını veplotlykodunu birleştirirBirçok zaman serisine iyi ölçeklenir
Etkileşimli grafikten statik
ggplot2grafiklerine dönüştürülebilir
2.1 Tek Bir Zaman Serisinin Grafiği
30 dakikalık bir örnekleme aralığında megawatt cinsinden enerji talebini içeren popüler bir zaman serisi olan taylor_30_min ile başlayalım. Bu tek bir zaman serisidir.
glimpse(taylor_30_min)Rows: 4,032
Columns: 2
$ date <dttm> 2000-06-05 00:00:00, 2000-06-05 00:30:00, 2000-06-05 01:00:0...
$ value <dbl> 22262, 21756, 22247, 22759, 22549, 22313, 22128, 21860, 21751...
plot_time_series() işlevi varsayılan olarak etkileşimli bir grafiksel grafik oluşturur.
İlk 2 bağımsız değişken olarak zaman içinde değişen tarih değişkenini (zaman tabanlı sütun,
.date_var) ve sayısal değişkeni (.value) sağlamanız yeterlidir..interactive = TRUEolduğunda,.plotly_slider = TRUE, grafiğin altına bir tarih kaydırıcısı ekler.
taylor_30_min %>%
plot_time_series(date,
value,
.interactive = TRUE, # <- Toggle this TRUE/FALSE
.plotly_slider = TRUE)2.2 Zaman Serisi Gruplarının Çizimi
Şimdi, M4 yarışmasından günlük sıklıkta örneklenen 4 zaman serisinin bir örneği olan m4_daily zaman serisi grupları içeren bir veri kümesine geçelim.
Gruplanmış verileri görselleştirmek, veri kümesini plot_time_series() işlevine aktarmadan önce group_by() ile gruplamak kadar basittir. Anahtar noktaları:
Gruplar 2 şekilde eklenebilir:
group_by()ile veya grup eklemek için…kullanılarak.Gruplar daha sonra
facet’a dönüştürülür..facet_ncol = 2, 2 sütunlu yönlü bir çizim döndürür.facet_scales = "free", her grafiğin x ve y ekseninin diğer grafiklerden bağımsız olarak ölçeklenmesine izin verir
m4_daily %>% group_by(id) %>% plot_time_series(date, value, .facet_ncol = 2, .facet_scales = "free",
.interactive = TRUE)2.3 Düzgünleştirici ile Trend Çizimi
Merak ediyor olabilirsiniz, tüm çizimlerde görünen o mavi çizginin ne olduğunu. Buna daha düzgünleştirici deniyor ve bir zaman serisindeki gürültü aracılığıyla eğilimi görselleştirmenin gerçekten harika bir yoludur.
Düzgünleştiriciyi şu şekilde ayarlayabiliriz:
Açma / kapama: .
smooth = TRUE/FALSESatırın esnekliğini değiştirin: .
smooth_period = "52 weeks"(30 günlük veriler) veya.smooth_span = 0,25(verilerin% 25’i) deneyin. Varsayılan olarak,.smooth_spanöncelik alır.
m4_weekly %>%
group_by(id) %>%
plot_time_series(date,
value,
# Smoother
.smooth = TRUE,
.smooth_span = 0.25, # <- Uses % of data
# .smooth_period = "52 weeks", # <- Uses windows of data
.facet_ncol = 2,
.facet_scales = "free",
.interactive = TRUE)2.4 Dönüşümleri ve Alt-Grupları Görselleştirme
Birden çok grup içeren saatlik veri kümesine geçelim. Şunları gösterebiliriz:
.value’ya günlük dönüşümüAlt grupları vurgulamak için
.color_varkullanalım.
Amaç, grupları facet grafiklerde sergilemek, ancak aynı anda değere bir log() dönüşümü yaparken veriler içindeki haftalık pencereleri (haftalık alt gruplar, week() kullanarak) vurgulamaktır. Bunu yapmak çok basit:
.value = log(value)Günlük Dönüşümünü uygularVeriler gruplandırılmamıştır, bu nedenle bir veya daha fazla faset sütunu sağlamak için
…kullanarak dahili olarak facetlar ekleyebiliriz..color_var = week(date)Tarih sütunu birlubridate :: week()numarasına dönüştürülür. Renk, hafta numaralarının her birine uygulanır.
m4_hourly %>%
group_by(id) %>%
plot_time_series(date,
log(value), # Apply a Log Transformation
.color_var = week(date), # Color applied to Week transformation
# Facet formatting
.facet_ncol = 2,
.facet_scales = "free",
.interactive = TRUE)2.5 Statik ggplot2 Görselleştirmeleri ve Özelleştirme
Tüm görselleştirmeler etkileşimli çizimden (uygulamaları keşfetmek ve parlak uygulamalar için harika) statik ggplot2 görselleştirmelerine (raporlar için harika) dönüştürülebilir.
Etkileşimli / Statik arasında geçiş yapılabilir:
.interaktif = TRUE / FALSEBaşlık, açıklama, x ve y ekseni etiketleri ekleyin:
.title,.color_lab, .x_labve.y_lab
taylor_30_min %>%
plot_time_series(date,
value,
.color_var = month(date, label = TRUE),
.interactive = FALSE, # <- Returns static ggplot
# Customization
.title = "Taylor's MegaWatt Data",
.x_lab = "Date (30-min intervals)",
.y_lab = "Energy Demand (MW)",
.color_lab = "Month") +
scale_y_continuous(labels = scales::comma_format())3 Otokorelasyon
Burada aşağıdaki grafikleri etkileşimli bir şekilde sunan plot_acf_diagnostics() işlevine odaklanacağız:
ACF ce PACF çizimleri.
CCF (Cross Correlation) çizimleri.
Etkileşimli çizimler için plotly, statik çizimler için ggplot2 paketlerini kullanmaktadır.
3.1 Otokorelasyon
Otokorelasyon, bir zaman serisinin gecikmeli değerlerine bağlı korelasyonun varlığıdır. Meslekten olmayan kişilerin terimleriyle bu, geçmiş tarihin gelecekteki tarihle ilgili olduğu anlamına gelir. Bu ilişkiyi bir ACF grafiği ile görselleştirebiliriz.
İlk olarak, plot_time_series() kullanarak taylor_30_min verisine bakacağımız zaman serisini çizelim.
taylor_30_min %>% plot_time_series(date, value, .interactive = T)Bu seri, yaklaşık 3 ay boyunca 30 dakikalık aralıklarla alınan saatlik elektrik talebini temsil etmektedir. Serideki otokorelasyonu yeni bir fonksiyon olan plot_acf_diagnostics() kullanarak görselleştirebiliriz.
taylor_30_min %>% plot_acf_diagnostics(date, value, .interactive = T)plot_acf_diagnostics() ’den şunu elde ederiz:
ACF Grafiği: Seri ile her aşamalı gecikme (x ekseni) arasındaki ilişkiyi ifade eden otomatik düzeltme (y ekseni).
PACF Grafiği: Kısmi otokorelasyon ve gecikmeler. Kısmi Otokorelasyon, her progresif ACF’nin öngörülebilirliğe ne kadar katkıda bulunduğunu gösterir. Başka bir deyişle, birbirleriyle ilişkili gecikmelerin ağırlığı azaltılır, böylece en önemli gecikmeler mevcuttur.
Bu 2 görselleştirme, ilişkileri modellememize ve tahmine dayalı tahminler geliştirmemize yardımcı olur:
Mevsimsellik: Bir ilişkiyi modellemek için kullanabileceğimiz Olası Fourier Serileri
Tahmin Edici Olarak Gecikmeler: Modellerimize dahil edilecek önemli gecikmeler bulabiliriz.
3.2 Gruplanmış ACF ve PACF Grafikleri
Genellikle zaman serilerinde birden fazla seriyle uğraşırız - bunlara gruplar denir. 4 grup içeren farklı bir saatlik veri kümesine, m4_hourly’ye geçelim.
m4_hourly %>% group_by(id) %>% plot_time_series(date, value, .facet_ncol = 2, .facet_scale = "free",
.interactive = T)ACF ve PACF grafiklerini plot_acf_diagnostics () kullanarak kolayca elde edebiliriz. .lags = "14 days" kullanarak 14 günlük gecikmeleri izole edebiliriz.
m4_hourly %>%
group_by(id) %>%
plot_acf_diagnostics(
date,
value, # ACF & PACF
.lags = "14 days", # 14-Days of hourly lags
.interactive = T
)Grupları kullanmak, zaman serilerini her zaman serisini ayrı ayrı analiz etmekten çok daha hızlı değerlendirmemize yardımcı olur. 4 zaman serisini hızlı bir şekilde değerlendirebiliyoruz.
Gruplanmış analiz, zaman serileri arasındaki benzerlikleri ve farklılıkları vurgulayabilir. Günlük sıklığa ek olarak H150 ve H410’da 1 haftada ani artışlar olduğunu görebiliriz.
3.3 Çapraz Korelasyon (Cross Correlation)
Buradaki son örnek, dış yordayıcıları bulmak için önemli bir teknik olan Çapraz Korelasyondur. Walmart için haftalık satışları, çeşitli departmanlardan oluşan zaman serisi gruplarını ve sıcaklık ve yakıt fiyatı dahil olmak üzere birkaç (potansiyel) öngörücüyü içeren yeni bir zaman serisi olan walmart_sales_weekly ile başlıyoruz.
glimpse(walmart_sales_weekly)Rows: 1,001
Columns: 17
$ id <fct> 1_1, 1_1, 1_1, 1_1, 1_1, 1_1, 1_1, 1_1, 1_1, 1_1, 1_1,...
$ Store <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
$ Dept <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
$ Date <date> 2010-02-05, 2010-02-12, 2010-02-19, 2010-02-26, 2010-...
$ Weekly_Sales <dbl> 24924.50, 46039.49, 41595.55, 19403.54, 21827.90, 2104...
$ IsHoliday <lgl> FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,...
$ Type <chr> "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A",...
$ Size <dbl> 151315, 151315, 151315, 151315, 151315, 151315, 151315...
$ Temperature <dbl> 42.31, 38.51, 39.93, 46.63, 46.50, 57.79, 54.58, 51.45...
$ Fuel_Price <dbl> 2.572, 2.548, 2.514, 2.561, 2.625, 2.667, 2.720, 2.732...
$ MarkDown1 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
$ MarkDown2 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
$ MarkDown3 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
$ MarkDown4 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
$ MarkDown5 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
$ CPI <dbl> 211.0964, 211.2422, 211.2891, 211.3196, 211.3501, 211....
$ Unemployment <dbl> 8.106, 8.106, 8.106, 8.106, 8.106, 8.106, 8.106, 8.106...
Haftalık Satışlar ile Sıcaklık ve Yakıt Fiyatı arasında .ccf_vars kullanarak Çapraz Korelasyonları görselleştirebiliriz.
walmart_sales_weekly %>%
select(id, Date, Weekly_Sales, Temperature, Fuel_Price) %>%
group_by(id) %>%
plot_acf_diagnostics(
Date,
Weekly_Sales, # ACF & PACF
.ccf_vars = c(Temperature, Fuel_Price), # CCFs
.show_ccf_vars_only = TRUE, # Toggle just CCFs?
.lags = "2 years", # Lags
.interactive = T
)4 Mevsimsellik
plot_seasonal_diagnostics (), zaman serisi mevsimselliğini görselleştirmek için etkileşimli ve ölçeklenebilir bir işlevdir.
Aşağıdaki mantığı kullanarak dahil edilecek bir alt özellik yelpazesini tespit etmek için dahili hesaplamalar gerçekleştirilir:
Minimum öznitelik, ardışık zaman damgaları arasındaki medyan farkına göre seçilir
Maksimum öznitelik, 2 tam döneme göre seçilir.
Örnek: 2 haftadan uzun süren saatlik zaman damgası verileri şu özelliklere sahip olacaktır: "hour", "wday.lbl" ve "week".
Bu işlev, dplyr :: group_by () ile yapılan gruplanmış data.frame ve tibbles’a uyumludur.
Gruplanmış veriler için, döndürülen otomatik özellik seçimi, alt gruplar içindeki tüm özelliklerin bir koleksiyonudur. Bu, bazı gruplar için anlamsız olsalar bile ekstra özelliklerin geri döndüğü anlamına gelir.
.value parametresi dönüşümlere uyar (ör. .value = log (sales))
Mevsimsel çizimler:
taylor_30_min %>% plot_seasonal_diagnostics(date, value, .interactive = T)Gruplanmış mevsimsel çizimler:
m4_hourly %>% group_by(id) %>% plot_seasonal_diagnostics(date, value, .interactive = T)4.1 STL Diagnostikleri
plot_stl_diagnostics () işlevi Mevsimsel Eğilim-Düşük ayrışımı (Seasonal-Trend-Loess decomposition) üretir. İşlev, veri çerçeveleri üzerinde çalışması ve dplyr gruplarıyla çalışmak üzere tasarlanması açısından “derli toplu” dur.
STL yöntemi, temel alınan stats :: stl () yöntemini kullanarak zaman serisi ayrıştırmasını uygular. Ayrıştırma, “mevsim” ve “eğilim” bileşenlerini “kalan” bırakarak “gözlemlenen” değerlerden ayırır.
Kullanıcı iki parametreyi kontrol edebilir: .frequency ve .trend.
.frequencyparametresi, “gözlemlenen” değerlerden kaldırılan “mevsim” bileşenini ayarlar..trendparametresi, kullanılan trend penceresini (stl ()’dent.windowparametresi) ayarlar.
Kullanıcı, zamana dayalı süreler (ör. “6 hafta”) veya sayısal değerler (ör. 180) veya zaman ölçeğine göre sıklığı ve / veya eğilimi otomatik olarak seçen “otomatik” olarak hem .frequency hem de .trend sağlayabilir.
m4_hourly %>% group_by(id) %>% plot_stl_diagnostics(date, value, .frequency = "auto",
.trend = "auto", .feature_set = c("observed", "season", "trend", "remainder"),
.interactive = T)5 Anomali Tespiti
Anormallik algılama, zaman serisi analizinin önemli bir parçasıdır:
Anormallikleri tespit etmek özel olayları ifade edebilir
Anormallikleri temizlemek tahmin hatasını iyileştirebilir
Burada, anormallikleri ölçekte görselleştirmek ve otomatik olarak tespit etmek için plot_anomaly_diagnostics () ve tk_anomaly_diagnostics () işlevlerini ele alacağız.
Veri seti:
glimpse(walmart_sales_weekly)Rows: 1,001
Columns: 17
$ id <fct> 1_1, 1_1, 1_1, 1_1, 1_1, 1_1, 1_1, 1_1, 1_1, 1_1, 1_1,...
$ Store <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
$ Dept <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
$ Date <date> 2010-02-05, 2010-02-12, 2010-02-19, 2010-02-26, 2010-...
$ Weekly_Sales <dbl> 24924.50, 46039.49, 41595.55, 19403.54, 21827.90, 2104...
$ IsHoliday <lgl> FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,...
$ Type <chr> "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A",...
$ Size <dbl> 151315, 151315, 151315, 151315, 151315, 151315, 151315...
$ Temperature <dbl> 42.31, 38.51, 39.93, 46.63, 46.50, 57.79, 54.58, 51.45...
$ Fuel_Price <dbl> 2.572, 2.548, 2.514, 2.561, 2.625, 2.667, 2.720, 2.732...
$ MarkDown1 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
$ MarkDown2 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
$ MarkDown3 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
$ MarkDown4 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
$ MarkDown5 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
$ CPI <dbl> 211.0964, 211.2422, 211.2891, 211.3196, 211.3501, 211....
$ Unemployment <dbl> 8.106, 8.106, 8.106, 8.106, 8.106, 8.106, 8.106, 8.106...
Anormalliklerle ilgili verileri elde etmek için ön işleme fonksiyonu olan tk_anomaly_diagnostics () kullanıyoruz.
Anormallik tespiti için tk_anomaly_diagnostics () yöntemi, zaman serilerindeki aykırı değerleri tespit etmek için 2 adımlı bir süreç uygular.
1.adım: STL ayrıştırma ile trendden ve mevsimsellikten ayırma.
2.adım: anomli tespiti.
“Trend” ve “mevsim” (mevsimsellik) kaldırıldıktan sonra, “kalan” üzerinde anormallik tespiti yapılır. Anormallikler belirlenir ve sınırlar (recomposed_l1 ve recomposed_l2) belirlenir.
Anormallik Algılama Yöntemi, medyan +/- 25’lik bir iç çeyrek aralığı (IQR) kullanır.
IQR Ayarı, alfa parametresi: Varsayılan alfa = 0,05 ile sınırlar, 25/75 taban çizgisini 3 IQR Faktörü 3 (3X) ile genişleterek belirlenir. IQR Faktörü = 0.15 / alfa (dolayısıyla alfa = 0.05 ile 3X):
Sınırları kontrol eden IQR Faktörünü artırmak için alfa’yı azaltın, bu da aykırı değer olmayı zorlaştırır.
Aykırı değer olmayı kolaylaştırmak için alfa’yı artırın.
IQR aykırı değer algılama yöntemi, tahmini :: tsoutliers () içinde kullanılır.
Twitter’ın
AnomalyDetectionpaketi tarafından benzer bir aykırı değer algılama yöntemi kullanılır.Hem Twitter hem de
forecast::tsoutliersyöntemleri Business Science’ın anomalize paketinde uygulanmıştır.
walmart_sales_weekly %>% group_by(Store, Dept) %>% tk_anomaly_diagnostics(Date, Weekly_Sales)# A tibble: 1,001 x 13
# Groups: Store, Dept [7]
Store Dept Date observed season trend remainder seasadj remainder_l1
<dbl> <dbl> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 2010-02-05 24924. 874. 19967. 4083. 24050. -15981.
2 1 1 2010-02-12 46039. -698. 19835. 26902. 46737. -15981.
3 1 1 2010-02-19 41596. -1216. 19703. 23108. 42812. -15981.
4 1 1 2010-02-26 19404. -821. 19571. 653. 20224. -15981.
5 1 1 2010-03-05 21828. 324. 19439. 2064. 21504. -15981.
6 1 1 2010-03-12 21043. 471. 19307. 1265. 20572. -15981.
7 1 1 2010-03-19 22137. 920. 19175. 2041. 21217. -15981.
8 1 1 2010-03-26 26229. 752. 19069. 6409. 25478. -15981.
9 1 1 2010-04-02 57258. 503. 18962. 37794. 56755. -15981.
10 1 1 2010-04-09 42961. 1132. 18855. 22974. 41829. -15981.
# ... with 991 more rows, and 4 more variables: remainder_l2 <dbl>,
# anomaly <chr>, recomposed_l1 <dbl>, recomposed_l2 <dbl>
5.1 Anomalilerin Görselleştirilmesi
walmart_sales_weekly %>% group_by(Store, Dept) %>% plot_anomaly_diagnostics(Date,
Weekly_Sales, .facet_ncol = 2)6 Zaman Serileri Modelleme: modeltime
6.1 1.adım: verinin alınıp eğitim ve test verisi olarak ayrıştırılması
Veri seti:
m750 <- m4_monthly %>% filter(id == "M750")Görselleştirme:
m750 %>% plot_time_series(date, value, .interactive = T)Zaman serisini bölme:
# Split Data 80/20
splits <- initial_time_split(m750, prop = 0.9)6.2 2.adım: birçok model hazırlayıp eğitme
modeltime ve parsnip birleştirerek kolayca düzinelerce tahmin modeli oluşturabiliriz. Ön işleme eklemek için iş akışları arayüzünü de kullanabiliriz! Tahmin olasılıklarınız sonsuzdur. Birkaç temel model geliştirelim:
ARIMA
Exponential Smoothing
Linear Regression
MARS (Multivariate Adaptive Regression Splines)
modeltime modelleri (ör. arima_reg()), modelde bir tarih veya tarih saat özelliği ile oluşturulur. Çoğu modelin fit gibi bir formül içerdiğini göreceksiniz (değer ~ tarih, veri).
parsnip modelleri (ör. linear_reg ()) tipik olarak tarih özelliklerine sahip olmamalıdır, ancak tarihlerin türevlerini içerebilir (ör. Ay, yıl vb.). Sıklıklafit (değer ~ sayısal (tarih) + ay (tarih), veri) gibi formüller göreceksiniz.
6.2.1 model 1: auto-arima
# Model 1: auto_arima ----
model_fit_arima_no_boost <- arima_reg() %>% set_engine(engine = "auto_arima") %>%
fit(value ~ date, data = training(splits))
# > frequency = 12 observations per 1 year6.2.2 model 2: boosted auto-arima
# Model 2: arima_boost ----
model_fit_arima_boosted <- arima_boost(min_n = 2, learn_rate = 0.015) %>% set_engine(engine = "auto_arima_xgboost") %>%
fit(value ~ date + as.numeric(date) + factor(month(date, label = TRUE), ordered = F),
data = training(splits))
# > frequency = 12 observations per 1 year6.2.3 model 3: exponential smoothing
# Model 3: ets Error-Trend-Season (ETS) ----
model_fit_ets <- exp_smoothing() %>% set_engine(engine = "ets") %>% fit(value ~ date,
data = training(splits))
# > frequency = 12 observations per 1 year6.2.4 model 4: prophet
# Model 4: prophet ----
model_fit_prophet <- prophet_reg() %>% set_engine(engine = "prophet") %>% fit(value ~
date, data = training(splits))
# > Disabling weekly seasonality. Run prophet with weekly.seasonality=TRUE to
# override this. > Disabling daily seasonality. Run prophet with
# daily.seasonality=TRUE to override this.6.2.5 model 5: lineer regression
# Model 5: lm ----
model_fit_lm <- linear_reg() %>% set_engine("lm") %>% fit(value ~ as.numeric(date) +
factor(month(date, label = TRUE), ordered = FALSE), data = training(splits))6.2.6 model 6: MARS
# Model 6: earth Multivariate Adaptive Regression Spline ----
model_spec_mars <- mars(mode = "regression") %>% set_engine("earth")
recipe_spec <- recipe(value ~ date, data = training(splits)) %>% step_date(date,
features = "month", ordinal = FALSE) %>% step_mutate(date_num = as.numeric(date)) %>%
step_normalize(date_num) %>% step_rm(date)
wflw_fit_mars <- workflow() %>% add_recipe(recipe_spec) %>% add_model(model_spec_mars) %>%
fit(training(splits))6.3 3.adım: modellerin Model Table’a aktarılması
models_tbl <- modeltime_table(model_fit_arima_no_boost, model_fit_arima_boosted,
model_fit_ets, model_fit_prophet, model_fit_lm, wflw_fit_mars)
models_tbl# Modeltime Table
# A tibble: 6 x 3
.model_id .model .model_desc
<int> <list> <chr>
1 1 <fit[+]> ARIMA(0,1,1)(0,1,1)[12]
2 2 <fit[+]> ARIMA(0,1,1)(0,1,1)[12] W/ XGBOOST ERRORS
3 3 <fit[+]> ETS(M,A,A)
4 4 <fit[+]> PROPHET
5 5 <fit[+]> LM
6 6 <workflow> EARTH
6.4 4.adım: test verisine karşı model kalibrasyonu
calibration_tbl <- models_tbl %>% modeltime_calibrate(new_data = testing(splits))
calibration_tbl# Modeltime Table
# A tibble: 6 x 5
.model_id .model .model_desc .type .calibration_da~
<int> <list> <chr> <chr> <list>
1 1 <fit[+]> ARIMA(0,1,1)(0,1,1)[12] Test <tibble [31 x 4~
2 2 <fit[+]> ARIMA(0,1,1)(0,1,1)[12] W/ XGBOOS~ Test <tibble [31 x 4~
3 3 <fit[+]> ETS(M,A,A) Test <tibble [31 x 4~
4 4 <fit[+]> PROPHET Test <tibble [31 x 4~
5 5 <fit[+]> LM Test <tibble [31 x 4~
6 6 <workflow> EARTH Test <tibble [31 x 4~
6.5 5.adım: test verisi tahmini ve doğruluğu geliştirme
Test Hatasını görselleştirmek, etkileşimli grafiksel görselleştirmeyi kullanarak yapmak kolaydır (Legend kullanarak modellerin görünürlüğünü değiştirebiliriz).
calibration_tbl %>%
modeltime_forecast(
new_data = testing(splits),
actual_data = m750
) %>%
plot_modeltime_forecast(
.legend_max_width = 25, # For mobile screens
.interactive = T
)Test seti tahminini görselleştirmekten:
Model 1 ve 2: ARIMA & ARIMA Boost iyi performans gösteriyor. Auto ARIMA kullandığımız için her iki modelde de “otomatik” bileşenler var. XGBoost bileşeni, belirtilen parametrelere sahiptir. Ayarlayarak daha iyi bir doğruluk elde edebiliriz, ancak ARIMA bileşeni bu veriler üzerinde iyi çalıştığı için ek iyileştirme düşük olabilir.
Model 3: ETS (M, A, A) en iyi performansı gösteriyor. % 80 güven aralığı, grubun en dar olanıdır ve bu, bekleme setinin iyi modellendiğini gösterir.
Model 4: PROPHET, ARIMA modelleriyle karşılaştırılabilir, ancak biraz daha geniş bir test hatası güven aralığına sahiptir.
Model 5: LM, yerel trendi abartıyor. Bunun nedeni, eğilim bileşeninin değişim noktalarını hesaba katmayan basit bir doğrusal çizgi olmasıdır.
Model 6: EARTH yerel eğilime fazla uyuyor. Bunun nedeni, değişim noktalarının sayısını ayarlamadığımız için, algoritmanın değişim noktalarını otomatik olarak hesaplamasıdır.
Doğruluk metrikleri:
MAE - Mean absolute error,
mae()MAPE - Mean absolute percentage error,
mape()MASE - Mean absolute scaled error,
mase()SMAPE - Symmetric mean absolute percentage error,
smape()RMSE - Root mean squared error,
rmse()RSQ - R-squared,
rsq()
calibration_tbl %>% modeltime_accuracy() %>% table_modeltime_accuracy(.interactive = T)Doğruluk ölçümlerinden:
Model 3: ETS, 77 MAE ile burada açıkça kazanan modeldir.
Model 6: MARS, yerel trendi aşıyor. Bu, 0.55’in R-Karesinde çıkar.
6.6 6.adım: tüm veri için yeniden eğitilip gelecek tahminlerinin türetilmesi
refit_tbl <- calibration_tbl %>%
modeltime_refit(data = m750)
refit_tbl %>%
modeltime_forecast(h = "3 years", actual_data = m750) %>%
plot_modeltime_forecast(
.legend_max_width = 25, # For mobile screens
.interactive = T
)Modellerin hepsi değişti! (Evet - bu yeniden eğitme için kritik noktadır)
LM modeli şimdi çok daha iyi görünüyor çünkü doğrusal eğilim çizgisi artık daha uzun vadeli eğilimi izleyen yeni verilere uyuyor.
EARTH modeli, kısa vadeli eğilimi daha çok temsil eden bir eğilime sahiptir.
PROPHET modelinin EARTH modeline çok benzer bir eğilimi vardır (bunun nedeni, her iki modelleme algoritmasının eğilimi modellemek için değişim noktaları kullanması ve peygamberin otomatik algoritmasının uyum sağlamada daha iyi bir iş çıkarmasıdır).
ETS modeli (M, A, A) yerine (A, A, A) olarak değiştirildi.
ARIMA modeli güncellendi ve yükselişi daha iyi yakaladı.
Bu, yeniden eğitmenin (potansiyel) faydasıdır.
Çoğu zaman yeniden eğitmemek iyi bir fikirdir. Yeniden eğitme:
Modelinizi ve ön işleme adımlarınızı alır
Modeli yeni verilere yeniler
Herhangi bir otomasyonu yeniden hesaplar. Bu şunları içerir:
- Doğrusal Model için uzun vadeli eğilimi yeniden hesaplamak
- Dünya Modeli için değişim noktalarını yeniden hesaplama
- ARIMA ve ETS parametrelerini yeniden hesaplama
Tüm parametre seçimlerini korur. Bu şunları içerir:
- Boosted ARIMA min_n = 2’deki XGBoost Parametreleri, learn_rate = 0.015.
- Otomatik hesaplamalar olmayan diğer varsayılanlar kullanılır.